Opi käyttämään Reactin Error Boundary -rajoja hookien kanssa resurssien latausvirheiden hallintaan, parantaen käyttökokemusta ja sovelluksen vakautta.
Vankka resurssien lataus Reactissa: Error Boundary -rajojen hallinta Hookien avulla
Nykyaikaisissa verkkosovelluksissa resurssien asynkroninen lataaminen on yleinen käytäntö. Olipa kyseessä datan noutaminen API-rajapinnasta, kuvien lataaminen tai moduulien tuominen, mahdollisten virheiden käsittely resurssien latauksen aikana on olennaista sujuvan käyttökokemuksen kannalta. Reactin Error Boundary -rajat tarjoavat mekanismin JavaScript-virheiden sieppaamiseen missä tahansa niiden lapsikomponenttipuussa, virheiden kirjaamiseen ja varakäyttöliittymän näyttämiseen koko sovelluksen kaatumisen sijaan. Tässä artikkelissa tutkitaan, miten Error Boundary -rajoja voidaan tehokkaasti käyttää yhdessä React Hookien kanssa resurssien latausvirheiden hallintaan.
Error Boundary -rajojen ymmärtäminen
Ennen React 16:ta käsittelemättömät JavaScript-virheet komponentin renderöinnin aikana vioittivat Reactin sisäistä tilaa ja aiheuttivat kryptisiä virheitä seuraavissa renderöinneissä. Error Boundary -rajat ratkaisevat tämän toimimalla yleisinä sieppauslohkoina virheille, jotka tapahtuvat niiden lapsikomponenteissa. Ne ovat React-komponentteja, jotka toteuttavat jommankumman tai molemmat seuraavista elinkaarimetodeista:
static getDerivedStateFromError(error): Tämä staattinen metodi kutsutaan sen jälkeen, kun alikomponentti on heittänyt virheen. Se saa argumenttina heitetyn virheen ja palauttaa arvon komponentin tilan päivittämiseksi.componentDidCatch(error, info): Tämä elinkaarimetodi kutsutaan sen jälkeen, kun alikomponentti on heittänyt virheen. Se saa argumentteina heitetyn virheen sekä objektin, joka sisältää tietoa siitä, mikä komponentti virheen heitti. Voit käyttää sitä virhetietojen kirjaamiseen.
On tärkeää huomata, että Error Boundary -rajat sieppaavat virheitä vain renderöintivaiheessa, elinkaarimetodeissa ja koko alapuolisen puun konstruktoreissa. Ne eivät sieppaa virheitä seuraavissa tapauksissa:
- Tapahtumankäsittelijät (lisätietoja alla olevassa osiossa)
- Asynkroninen koodi (esim.
setTimeout- tairequestAnimationFrame-takaisinkutsut) - Palvelinpuolen renderöinti
- Virheet, jotka heitetään itse Error Boundary -rajassa (eikä sen lapsissa)
Error Boundary -rajat ja React Hookit: Tehokas yhdistelmä
Vaikka luokkakomponentteja käytettiin perinteisesti Error Boundary -rajojen toteuttamiseen, React Hookit tarjoavat ytimekkäämmän ja funktionaalisemman lähestymistavan. Voimme luoda uudelleenkäytettävän useErrorBoundary-hookin, joka kapseloi virheenkäsittelylogiikan ja tarjoaa kätevän tavan kääriä komponentteja, jotka saattavat heittää virheitä resurssien latauksen aikana.
Mukautetun useErrorBoundary-Hookin luominen
Tässä on esimerkki useErrorBoundary-hookista:
import { useState, useCallback } from 'react';
function useErrorBoundary() {
const [error, setError] = useState(null);
const resetError = useCallback(() => {
setError(null);
}, []);
const captureError = useCallback((e) => {
setError(e);
}, []);
const ErrorBoundary = useCallback(({ children, fallback }) => {
if (error) {
return fallback ? fallback : An error occurred: {error.message || String(error)};
}
return children;
}, [error]);
return { ErrorBoundary, captureError, error, resetError };
}
export default useErrorBoundary;
Selitys:
useState: KäytämmeuseState-hookia virhetilan hallintaan. Se asettaa aluksi virheen arvoksinull.useCallback: KäytämmeuseCallback-hookia funktioidenresetErrorjacaptureErrormemoisoimiseen. Tämä on hyvä käytäntö, jolla estetään tarpeettomat uudelleenrenderöinnit, jos nämä funktiot välitetään propseina.ErrorBoundary-komponentti: Tämä onuseCallback-hookilla luotu funktionaalinen komponentti, joka ottaa vastaanchildren- ja valinnaisenfallback-propsin. Jos tilassa on virhe, se renderöi joko annetunfallback-komponentin tai oletusarvoisen virheilmoituksen. Muussa tapauksessa se renderöi lapsielementit. Tämä toimii meidän Error Boundary -rajamme. Riippuvuuslista `[error]` varmistaa, että se renderöidään uudelleen, kun `error`-tila muuttuu.captureError-funktio: Tätä funktiota käytetään asettamaan virhetila. Kutsut sitätry...catch-lohkossa, kun lataat resursseja.resetError-funktio: Tämä funktio tyhjentää virhetilan, jolloin komponentti voi renderöidä lapsensa uudelleen (ja mahdollisesti yrittää resurssin lataamista uudelleen).
Resurssien latauksen toteuttaminen virheenkäsittelyllä
Katsotaan nyt, miten tätä hookia käytetään resurssien latausvirheiden käsittelyyn. Tarkastellaan komponenttia, joka hakee käyttäjätietoja API-rajapinnasta:
import React, { useState, useEffect } from 'react';
import useErrorBoundary from './useErrorBoundary';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const { ErrorBoundary, captureError, error, resetError } = useErrorBoundary();
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (e) {
captureError(e);
}
};
fetchData();
}, [userId, captureError]);
if (error) {
return (
Failed to load user data. {user.name}
Email: {user.email}
{/* Other user details */}Selitys:
- Tuomme
useErrorBoundary-hookin. - Kutsumme hookia saadaksemme
ErrorBoundary-komponentin,captureError-funktion,error-tilan jaresetError-funktion. useEffect-hookin sisällä käärimme API-kutsuntry...catch-lohkoon.- Jos API-kutsun aikana tapahtuu virhe, kutsumme
captureError(e)asettaaksemme virhetilan. - Jos
error-tila on asetettu, renderöimmeErrorBoundary-komponentin. Tarjoamme mukautetunfallback-propsin, joka näyttää virheilmoituksen ja "Yritä uudelleen"-painikkeen. Painikkeen napsauttaminen kutsuuresetError-funktiota, joka tyhjentää virhetilan, mikä käynnistää uudelleenrenderöinnin ja uuden yrityksen hakea dataa. - Jos virhettä ei tapahtunut ja käyttäjätiedot on ladattu, renderöimme käyttäjäprofiilin tiedot.
Erityyppisten resurssien latausvirheiden käsittely
Erityyppiset resurssien latausvirheet saattavat vaatia erilaisia käsittelystrategioita. Tässä on joitain yleisiä skenaarioita ja miten niihin voidaan puuttua:
Verkkovirheet
Verkkovirheitä tapahtuu, kun asiakas ei pysty muodostamaan yhteyttä palvelimeen (esim. verkkokatkoksen tai palvelimen toimintakatkon vuoksi). Yllä oleva esimerkki käsittelee jo perustason verkkovirheet käyttämällä `response.ok`. Haluat ehkä lisätä kehittyneempää virheentunnistusta, esimerkiksi:
// fetchData-funktion sisällä
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
// Harkitse tiettyjen virhekoodien käsittelyn lisäämistä
if (response.status === 404) {
throw new Error("Käyttäjää ei löytynyt");
} else if (response.status >= 500) {
throw new Error("Palvelinvirhe. Yritä myöhemmin uudelleen.");
} else {
throw new Error(`HTTP-virhe! Tila: ${response.status}`);
}
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error.message === 'Failed to fetch') {
// Todennäköisesti verkkovirhe
captureError(new Error('Verkkovirhe. Tarkista internet-yhteytesi.'));
} else {
captureError(error);
}
}
Tässä tapauksessa voit näyttää käyttäjälle viestin, joka ilmoittaa verkkoyhteysongelmasta ja kehottaa häntä tarkistamaan internet-yhteytensä.
API-virheet
API-virheitä tapahtuu, kun palvelin palauttaa virhevastauksen (esim. 400 Bad Request tai 500 Internal Server Error). Kuten yllä on esitetty, voit tarkistaa `response.status`-arvon ja käsitellä nämä virheet asianmukaisesti.
Datan jäsentämisvirheet
Datan jäsentämisvirheitä tapahtuu, kun palvelimelta saatu vastaus ei ole odotetussa muodossa eikä sitä voida jäsentää (esim. virheellinen JSON). Voit käsitellä näitä virheitä käärimällä response.json()-kutsun try...catch-lohkoon:
// fetchData-funktion sisällä
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP-virhe! Tila: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error instanceof SyntaxError) {
captureError(new Error('Datan jäsentäminen palvelimelta epäonnistui.'));
} else {
captureError(error);
}
}
Kuvien latausvirheet
Kuvien latauksessa voit käyttää onError-tapahtumankäsittelijää <img>-tagissa:
function MyImage({ src, alt }) {
const { ErrorBoundary, captureError } = useErrorBoundary();
const [imageLoaded, setImageLoaded] = useState(false);
const handleImageLoad = () => {
setImageLoaded(true);
};
const handleImageError = (e) => {
captureError(new Error(`Kuvan lataaminen epäonnistui: ${src}`));
};
return (
Kuvan lataaminen epäonnistui.